package com.aizhixin.lab.course.course.service;

import cn.hutool.core.date.DateTime;
import com.aizhixin.lab.common.core.ApiReturnConstants;
import com.aizhixin.lab.common.core.DataValidity;
import com.aizhixin.lab.common.dto.SortDTO;
import com.aizhixin.lab.common.utils.PageJdbcUtil;
import com.aizhixin.lab.company.domain.SignData;
import com.aizhixin.lab.company.domain.SignInDomain;
import com.aizhixin.lab.course.course.domain.ReleaseSignInData;
import com.aizhixin.lab.course.course.domain.StuSignInData;
import com.aizhixin.lab.course.course.domain.StuSignRecordDomain;
import com.aizhixin.lab.course.course.entity.ReleaseSignIn;
import com.aizhixin.lab.course.course.entity.StuSignIn;
import com.aizhixin.lab.company.entity.User;
import com.aizhixin.lab.course.course.repository.ReleaseSigInRepository;
import com.aizhixin.lab.course.course.repository.StuSignInRepository;
import com.aizhixin.lab.company.repository.UserRepository;
import com.aizhixin.lab.course.classes.entity.CourseClass;
import com.aizhixin.lab.course.classes.entity.CourseClassStu;
import com.aizhixin.lab.course.classes.repository.CourseClassRepository;
import com.aizhixin.lab.course.classes.repository.CourseClassStuRepository;
import com.aizhixin.lab.project.course.entity.ProjectClass;
import com.aizhixin.lab.project.course.entity.ProjectClassStu;
import com.aizhixin.lab.project.course.repository.ProjectClassRepository;
import com.aizhixin.lab.project.course.repository.ProjectClassStuRepository;
import com.aizhixin.lab.project.course.uilt.NumToChinese;
import com.aizhixin.lab.statistics.domain.GiveLessonsDomain;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class ReleaseSignInService {
    @Autowired
    private ReleaseSigInRepository sigInRepository;
    @Autowired
    private StuSignInRepository stuSignInRepository;
    @Autowired
    private CourseClassRepository courseClassRepository;
    @Autowired
    private CourseClassStuRepository stuRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PageJdbcUtil pageJdbcUtil;
    @Autowired
    private ProjectClassRepository projectClassRepository;
    @Autowired
    private ProjectClassStuRepository projectClassStuRepository;
    public Integer countStuUnSign(Long stuId){
        String sql="SELECT COUNT(c.id) FROM c_stu_sign_in c LEFT JOIN c_release_sign_in r ON c.sign_in_id=r.id WHERE c.stu_id="+stuId+" AND c.status=0 AND TO_DAYS(r.create_date)=TO_DAYS(NOW())";
        Integer countInt = pageJdbcUtil.getCountInt(sql);
        return countInt;
    }

    public SignData releaseSign(String classId, Date endDate, Long createBy, Integer type) {
        SignData signData = new SignData();
        List<Long> ids = new ArrayList<>();
        CourseClass courseClass = new CourseClass();
        List<CourseClassStu> courseClassStuList = new ArrayList<>();
        ProjectClass projectClass = new ProjectClass();
        List<ProjectClassStu> projectClassStuList = new ArrayList<>();
        ReleaseSignIn releaseSignIn = new ReleaseSignIn();
        List<StuSignIn> stuSignInList = new ArrayList<>();
        if (type == 10) {
            courseClass = courseClassRepository.findByIdAndDeleteFlag(classId, DataValidity.VALID.getState());
            courseClassStuList = stuRepository.findAllByDeleteFlagAndCourseClassIdIn(DataValidity.VALID.getState(), Arrays.asList(classId.split(",")));
            releaseSignIn.setId(UUID.randomUUID().toString());
            releaseSignIn.setCourseClassId(classId);
            releaseSignIn.setCourseId(courseClass.getCourseId());
            releaseSignIn.setCreateDate(new Date());
            releaseSignIn.setType(10);
            releaseSignIn.setStuNum(courseClassStuList.size());
            releaseSignIn.setCreateBy(createBy);
            String sql = "SELECT COUNT(*) FROM c_release_sign_in c WHERE c.course_class_id='" + releaseSignIn.getCourseClassId() + "' AND c.course_id='" + releaseSignIn.getCourseId() + "' AND TO_DAYS(c.create_date)=TO_DAYS(NOW())";
            releaseSignIn.setNum(NumToChinese.numToChinese(pageJdbcUtil.getCountInt(sql) + 1 + ""));
            for (CourseClassStu courseClassStu : courseClassStuList) {
                StuSignIn stuSignIn = new StuSignIn();
                stuSignIn.setId(UUID.randomUUID().toString());
                stuSignIn.setStatus(0);
                stuSignIn.setSignInId(releaseSignIn.getId());
                stuSignIn.setStuId(courseClassStu.getStuId());
                stuSignIn.setEndDate(endDate);
                ids.add(stuSignIn.getStuId());
                stuSignInList.add(stuSignIn);
            }
        } else {
            projectClass = projectClassRepository.findByIdAndDeleteFlag(classId, DataValidity.VALID.getState());
            projectClassStuList = projectClassStuRepository.findAllByDeleteFlagAndProjectClassIdIn(DataValidity.VALID.getState(), Arrays.asList(classId.split(",")));
            releaseSignIn.setId(UUID.randomUUID().toString());
            releaseSignIn.setCourseClassId(classId);
            releaseSignIn.setCourseId(projectClass.getProjectId());
            releaseSignIn.setCreateDate(new Date());
            releaseSignIn.setStuNum(projectClassStuList.size());
            releaseSignIn.setCreateBy(createBy);
            releaseSignIn.setType(20);
            String sql = "SELECT COUNT(*) FROM c_release_sign_in c WHERE c.course_class_id='" + releaseSignIn.getCourseClassId() + "' AND c.course_id='" + releaseSignIn.getCourseId() + "' AND TO_DAYS(c.create_date)=TO_DAYS(NOW())";
            releaseSignIn.setNum(NumToChinese.numToChinese(pageJdbcUtil.getCountInt(sql) + 1 + ""));
            for (ProjectClassStu projectClassStu : projectClassStuList) {
                StuSignIn stuSignIn = new StuSignIn();
                stuSignIn.setId(UUID.randomUUID().toString());
                stuSignIn.setStatus(0);
                stuSignIn.setSignInId(releaseSignIn.getId());
                stuSignIn.setStuId(projectClassStu.getStuId());
                stuSignIn.setEndDate(endDate);
                ids.add(stuSignIn.getStuId());
                stuSignInList.add(stuSignIn);
            }

        }
            sigInRepository.save(releaseSignIn);
            stuSignInRepository.save(stuSignInList);
            List<User> userList = userRepository.findAllByIdIn(ids);
            List<String> collect = userList.stream().filter(item -> {
                if (StringUtils.isEmpty(item.getOntoken())) {
                    return false;
                }
                return true;
            }).map(User::getOntoken).collect(Collectors.toList());
            signData.setIds(collect);
            signData.setSignInCode(releaseSignIn.getId());
            return signData;
        }


    public Map<String, Object> signIn(String code, Long stuId) {
        Map<String, Object> map = new HashMap<>();
        StuSignIn stuSignIn = stuSignInRepository.findBySignInIdAndStuId(code, stuId);
        if (Objects.isNull(stuId)){
            map.put(ApiReturnConstants.SUCCESS,false);
            map.put(ApiReturnConstants.MESSAGE,"暂无签到信息");
            return map;
        }
        if (new Date().getTime()>stuSignIn.getEndDate().getTime()){
            stuSignIn.setStatus(2);
        }else {
            stuSignIn.setStatus(1);
        }
        stuSignIn.setSignDate(new Date());
        stuSignInRepository.save(stuSignIn);
        map.put(ApiReturnConstants.SUCCESS,true);
        return map;
    }
    RowMapper<ReleaseSignInData> sv = new RowMapper<ReleaseSignInData>() {

        @Override
        public ReleaseSignInData mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            // TODO Auto-generated method stub
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            ReleaseSignInData domain = new ReleaseSignInData();
            domain.setId(rs.getString(1));
            domain.setCreatedDate(formatter.format(rs.getTimestamp(2)));
            domain.setTotalNum(rs.getInt(3));
            domain.setNum(rs.getInt(4));
            domain.setSignNum(rs.getString(5));
            return domain;
        }
    };

    public List<ReleaseSignInData> getSignTable(String courseId,String date){
        String  sql="SELECT r.id,r.create_date,r.stu_num,(SELECT COUNT(*) FROM c_stu_sign_in c WHERE c.sign_in_id=r.id AND c.status=0 ),r.num a FROM c_release_sign_in r WHERE r.course_id ='"+courseId+"'";
        if (date!=null){
            sql+=" AND r.create_date between '"+date+" 00:00:00' and '"+date+" 23:59:59' ORDER BY r.create_date DESC";
        }

        return pageJdbcUtil.getInfo(sql, sv);
    }
    public List<ReleaseSignInData> getProjectSignTable(String courseId,String date){
        String  sql="SELECT r.id,r.create_date,r.stu_num,(SELECT COUNT(*) FROM c_stu_sign_in c WHERE c.sign_in_id=r.id AND c.status=0 ),r.num a FROM c_release_sign_in r WHERE r.course_id ='"+courseId+"'";
        if (date!=null){
            sql+=" AND r.create_date between '"+date+" 00:00:00' and '"+date+" 23:59:59' ORDER BY r.create_date DESC";
        }

        return pageJdbcUtil.getInfo(sql, sv);
    }

    public Map<String, Object> findSignTable(String courseId,String date){
        Map<String, Object> map = new HashMap<>();
        map.put(ApiReturnConstants.SUCCESS,true);
        map.put(ApiReturnConstants.DATA,getSignTable(courseId, date));
        return map;
    }

    RowMapper<StuSignInData> sign = new RowMapper<StuSignInData>() {

        @Override
        public StuSignInData mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            // TODO Auto-generated method stub
            StuSignInData domain = new StuSignInData();
            domain.setStuId(rs.getLong(1));
            domain.setStuName(rs.getString(2));
            domain.setSex(rs.getString(3));
            domain.setCollegeName(rs.getString(4));
            domain.setProName(rs.getString(5));
            domain.setClassName(rs.getString(6));
            int anInt = rs.getInt(7);
            if (anInt==0){
                domain.setStatus("未签到");
            }else if (anInt==1){
                domain.setStatus("已签到");
            }else {
                domain.setStatus("已迟到");
            }
            return domain;
        }
    };
    public Map<String, Object> findSignTableInfo(SignInDomain domain){
        String sql="SELECT tu.JOB_NUM,tu.`name`,tu.SEX,t.`NAME`,tp.`NAME`,tc.`NAME`,c.`status` FROM c_stu_sign_in c LEFT JOIN t_user tu ON tu.id=c.stu_id LEFT JOIN t_classes tc ON tc.ID=tu.CLASS_ID LEFT JOIN t_professional tp ON tp.ID=tu.PROFESSIONAL_ID LEFT JOIN t_college t ON t.ID=tu.COLLEGE_ID WHERE c.sign_in_id='"+domain.getId()+"'";
        String countSql="SELECT count(*) FROM c_stu_sign_in c LEFT JOIN t_user tu ON tu.id=c.id LEFT JOIN t_classes tc ON tc.ID=tu.CLASS_ID LEFT JOIN t_professional tp ON tp.ID=tu.PROFESSIONAL_ID LEFT JOIN t_college t ON t.ID=tu.COLLEGE_ID WHERE c.sign_in_id='"+domain.getId()+"'";
        List<SortDTO> sort = new ArrayList<>();
        SortDTO dto1 = new SortDTO();
        dto1.setKey("c.status");
        dto1.setAsc(true);
        sort.add(dto1);
        SortDTO dto = new SortDTO();
        dto.setKey("c.sign_date");
        dto.setAsc(false);
        sort.add(dto);
       return pageJdbcUtil.getPageInfor(domain.getPageSize(),domain.getPageNumber(),sign,sort,sql,countSql);
    }
    public List<StuSignInData> findSignTableInfo(String id){
        String sql="SELECT tu.JOB_NUM,tu.`name`,tu.SEX,t.`NAME`,tp.`NAME`,tc.`NAME`,c.`status` FROM c_stu_sign_in c LEFT JOIN t_user tu ON tu.id=c.stu_id LEFT JOIN t_classes tc ON tc.ID=tu.CLASS_ID LEFT JOIN t_professional tp ON tp.ID=tu.PROFESSIONAL_ID LEFT JOIN t_college t ON t.ID=tu.COLLEGE_ID WHERE c.sign_in_id='"+id+"'";
        List<StuSignInData> info = pageJdbcUtil.getInfo(sql, sign);
        return info;
    }
    RowMapper<StuSignRecordDomain> record = new RowMapper<StuSignRecordDomain>() {

        @Override
        public StuSignRecordDomain mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            StuSignRecordDomain domain = new StuSignRecordDomain();
            domain.setId(rs.getString(1));
            domain.setCourseName(rs.getString(2));
            domain.setCreateDate(rs.getTimestamp(3));
            domain.setSignDate(rs.getTimestamp(4));
            domain.setTeacherName(rs.getString(6));
            int anInt = rs.getInt(5);
            if (anInt==0){
                domain.setStatus("未签到");
            }else if (anInt==1){
                domain.setStatus("已签到");
            }else {
                domain.setStatus("已迟到");
            }
            return domain;
        }
    };

    public List<StuSignRecordDomain> findStuSignRecord(Long stuId){
        String sql="SELECT c.id,cc.name,c.create_date,s.sign_date,s.status,t.name FROM c_release_sign_in c LEFT JOIN c_stu_sign_in s ON c.id=s.sign_in_id LEFT JOIN c_course cc ON c.course_id=cc.id LEFT JOIN t_user t ON t.id=c.create_by WHERE c.type=10 and DATE(c.create_date)=curdate() AND s.stu_id="+stuId+" ORDER BY s.status ASC,s.sign_date DESC";
        List<StuSignRecordDomain> info = pageJdbcUtil.getInfo(sql, record);
        return info;
    }
    RowMapper<StuSignRecordDomain> stuSignRecordDomainRowMapper = new RowMapper<StuSignRecordDomain>() {

        @Override
        public StuSignRecordDomain mapRow(ResultSet rs, int rowNum)
                throws SQLException {
            StuSignRecordDomain domain = new StuSignRecordDomain();
            domain.setId(rs.getString(1));
            domain.setProjectName(rs.getString(2));
            domain.setCreateDate(rs.getTimestamp(3));
            domain.setSignDate(rs.getTimestamp(4));
            domain.setTeacherName(rs.getString(6));
            int anInt = rs.getInt(5);
            if (anInt==0){
                domain.setStatus("未签到");
            }else if (anInt==1){
                domain.setStatus("已签到");
            }else {
                domain.setStatus("已迟到");
            }
            return domain;
        }
    };

    public List<StuSignRecordDomain> findSignRecord(Long stuId){
        String sql="SELECT c.id,cc.project_name,c.create_date,s.sign_date,s.status,t.name FROM c_release_sign_in c LEFT JOIN c_stu_sign_in s ON c.id=s.sign_in_id LEFT JOIN c_project cc ON c.course_id=cc.id LEFT JOIN t_user t ON t.id=c.create_by WHERE c.type=20 and DATE(c.create_date)=curdate() AND s.stu_id="+stuId+" ORDER BY s.status ASC,s.sign_date DESC";
        List<StuSignRecordDomain> info = pageJdbcUtil.getInfo(sql, stuSignRecordDomainRowMapper);
        return info;
    }
}
